home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / General App Samples / Rotating Rects (Pascal) ƒ / Rotating Rects.p < prev    next >
Encoding:
Text File  |  1995-04-10  |  9.9 KB  |  310 lines  |  [TEXT/MPS ]

  1. (*    Pascalized version of the C Rotating Rects graphics sample.
  2.         8/30/94 - dmh
  3. *)
  4.  
  5. PROGRAM RotnRects;
  6.  
  7. USES
  8.  ToolIntf, Events, Windows, Types, GraphicsTypes, GraphicsToolbox, GraphicsMacintosh, LayoutRoutines, MathRoutines, GraphicsRoutines, FontRoutines;
  9.  
  10. FUNCTION  GetWindowBoundsShape:gxShape; Forward;
  11. PROCEDURE DoDraw(aWindow: WindowPtr); Forward;
  12. PROCEDURE DoInitialization(aWindow: WindowPtr); Forward;
  13. PROCEDURE DoDispose(aWindow: WindowPtr); Forward;
  14.  
  15. PROCEDURE SetDefaultViewPort(gTheWindowsViewPort: gxViewPort); C; EXTERNAL;
  16.  
  17. VAR
  18.     gWindow:                                            WindowPtr;
  19.     gWindowBoundsShape:                        gxShape;
  20.     gTheWindowsViewPort:                        gxViewPort;    
  21.     theCurs:                                            CursHandle; 
  22.     newClient:                                        gxGraphicsClient;
  23.     dummyError:                                    gxGraphicsError;
  24.     windowQDRect:                                    Rect;
  25.     gTotalnumberOfRectanglesDrawn:        INTEGER;
  26.     gRectangleShape:                                gxShape;
  27.     gFixedWindowBounds:                        gxRectangle;
  28.     gRectangleColor:                                gxColor;
  29.     gChangeShapeFill:                                Boolean;
  30.  
  31. (*------ GetWindowBoundsShape -------------------------------------------------------------------------*)
  32.  
  33. FUNCTION  GetWindowBoundsShape:gxShape;
  34. VAR
  35.     theRect    :                    Rect;
  36.     QDtopLeft:                Point;
  37.     QDbotRight:                Point;
  38.     QDGXtopLeft:            gxPoint;
  39.     QDGXbotRight:            gxPoint;
  40.     theQDGXRect:            gxRectangle;
  41.     aRectanglePointer:    gxRectanglePointer;
  42.  
  43. BEGIN
  44.     (* The QuickDraw rect and points which represent the portRect of the window.  *)
  45.  
  46.     theRect := gWindow^.portRect;
  47.     QDtopLeft.h := theRect.left;
  48.     QDtopLeft.v := theRect.top;
  49.     QDbotRight.h := theRect.right;
  50.     QDbotRight.v := theRect.bottom;
  51.      
  52.     (* Convert the global Quickdraw coordinates to local fixed coordinates. *)
  53.     GXConvertQDPoint(QDtopLeft, gxViewPort (0), QDGXtopLeft);
  54.     GXConvertQDPoint(QDbotRight, gxViewPort (0), QDGXbotRight);
  55.  
  56.     (* Setup the dimensions for "gWindowBoundsShape" *)
  57.     theQDGXRect.top := QDGXtopLeft.y;
  58.     theQDGXRect.left := QDGXtopLeft.x;
  59.     theQDGXRect.bottom := QDGXbotRight.y;
  60.     theQDGXRect.right := QDGXbotRight.x;
  61.     
  62.     GetWindowBoundsShape := gxShape (GXNewRectangle(gxRectanglePointer(@theQDGXRect)));
  63. END;
  64.  
  65.  
  66.  
  67. (*------ EventLoop ------------------------------------------------------------------------------------*)
  68.  
  69. FUNCTION EventLoop:    Boolean;
  70. VAR
  71.     whichWindow:  WindowPtr;
  72.     event:                EventRecord;
  73.     whatToReturn:    Boolean;
  74.     dummy:            Boolean;
  75.  
  76. BEGIN
  77.     whatToReturn := TRUE;
  78.     dummy := WaitNextEvent(everyEvent, event, 0, nil);
  79.  
  80.     case event.what OF
  81.         updateEvt:
  82.             BEGIN
  83.                 BeginUpdate(WindowPtr (event.message));
  84.                 SetPort(gWindow);
  85.                 DoDraw(gWindow);
  86.                 EndUpdate(WindowPtr (event.message));
  87.             END;
  88.         
  89.         mouseDown:
  90.             case (FindWindow(event.where, whichWindow)) OF
  91.                 inSysWindow:
  92.                     SystemClick(event, whichWindow);
  93.                         
  94.                 inDrag:
  95.                     DragWindow(whichWindow, event.where, screenBits.bounds);
  96.  
  97.                 inGoAway:
  98.                     IF (TrackGoAway(whichWindow, event.where) = TRUE) THEN
  99.                         whatToReturn:= FALSE;
  100.  
  101.                 inContent:
  102.                     IF (whichWindow <> FrontWindow) THEN
  103.                          SelectWindow(whichWindow);
  104.             END;
  105.     END;
  106.  
  107.     EventLoop := whatToReturn;
  108. END;
  109.  
  110. (*------ DoInitialization ---------------------------------------------------------------------------------*)
  111. (* Set up the title and size of the window *)
  112.  
  113. PROCEDURE DoInitialization(aWindow: WindowPtr);
  114. VAR
  115.     windowViewPortParent:                    gxViewPort;
  116.     aRectanglePointer:                            gxRectanglePointer;
  117.  
  118. BEGIN
  119.     gChangeShapeFill := true;
  120.     gTotalnumberOfRectanglesDrawn := 0;
  121.      
  122.     (*
  123.         Get the viewPort that is attached to the window, and set the dither of this viewPort to 4.  Which
  124.         will mean that all objects that are drawn into window will be dithered at a dither level of 4.
  125.     *)
  126.      windowViewPortParent := GXGetWindowViewPort(aWindow);
  127.     GXSetViewPortDither(windowViewPortParent, 4);
  128.  
  129.     (* Get the bounds of the window, and create a gxRectangle that will fill the window *)
  130.     aRectanglePointer := GXGetShapeBounds(gWindowBoundsShape, 0, gFixedWindowBounds);
  131.     gRectangleShape := GXNewRectangle(gxRectanglePointer(@gFixedWindowBounds)); 
  132.     
  133.     (* Set up an HSV gxColor space to run the rectangles through... *)
  134.  
  135.     gRectangleColor.space := gxHSVSpace;
  136.     gRectangleColor.profile := nil;
  137.     gRectangleColor.hsv.hue := 0;
  138.     gRectangleColor.hsv.value := $FFFF;
  139.     gRectangleColor.hsv.saturation := $FFFF;
  140. END;
  141.  
  142.  
  143. (*------ DoDraw ---------------------------------------------------------------------------------------*)
  144.  
  145. PROCEDURE DoDraw(aWindow: WindowPtr);
  146. VAR
  147.     rectangleBoundsShape:        gxRectangle;
  148.     x:                                        fixed;
  149.     y:                                        fixed;
  150.     aRectanglePointer:            gxRectanglePointer;
  151.  
  152. BEGIN
  153.     IF (gTotalnumberOfRectanglesDrawn = 110) THEN
  154.     BEGIN
  155.         
  156.         (*
  157.               Time to rebuild the gxRectangle...   Dispose of the "old" rectangle, and re-create a
  158.              rectangle that will fill the window 
  159.         *)
  160.         GXDisposeShape(gRectangleShape); 
  161.         gRectangleShape := GXNewRectangle(gxRectanglePointer(@gFixedWindowBounds)); 
  162.     
  163.         (*
  164.              Set the gxShapeFill type, alternate drawing the gxRectangle with a solid fill and a
  165.              gxClosedFrameFill
  166.         *)
  167.         IF (gChangeShapeFill = true) THEN
  168.         BEGIN
  169.              SetPort (aWindow);
  170.             EraseRect(aWindow^.portRect);
  171.             GXSetShapeFill (gRectangleShape, gxClosedFrameFill);
  172.                gChangeShapeFill := false;
  173.            END
  174.            ELSE
  175.             gChangeShapeFill := TRUE;
  176.                   
  177.         gTotalnumberOfRectanglesDrawn := 0;
  178.     END;
  179.     
  180.     GXSetShapeColor(gRectangleShape, gxColorPointer(@gRectangleColor));
  181.     GXDrawShape(gRectangleShape);
  182.  
  183.     gRectangleColor.hsv.hue := gRectangleColor.hsv.hue + $0300;
  184.     
  185.     (*
  186.     //    Get the new bounds of the rectangle after it has been scaled by calling GXScaleShape. Each call to GXScaleShape
  187.     //    changes the bounding shape (box) of the rectangle. Determine the center of the bounding box, pass the center
  188.     //    to the GXRotateShape call. This will have the rectagnel rotated about the center.
  189.     *)
  190.     aRectanglePointer := GXGetShapeBounds(gRectangleShape, 0, rectangleBoundsShape);
  191.     x := (rectangleBoundsShape.left + rectangleBoundsShape.right ) div 2;
  192.     y := (rectangleBoundsShape.top + rectangleBoundsShape.bottom) div 2;
  193.             
  194.     GXRotateShape(gRectangleShape, $00020000, x, y);
  195.     GXScaleShape(gRectangleShape, $0000F800, $0000F800, x, y);
  196.  
  197.     gTotalnumberOfRectanglesDrawn := gTotalnumberOfRectanglesDrawn +1;
  198. END;
  199.  
  200.  
  201. (*------ DoDispose -------------------------------------------------------------------------------------*)
  202.  
  203. PROCEDURE DoDispose(aWindow: WindowPtr);
  204. BEGIN
  205.      (*  
  206.     //    You should always dispose of your GX graphics objects before tossing your window. Why? It's generally good 
  207.     //    form and this approach guarantees that everything is disposed. If you had not disposed of everything, the
  208.     //    call to DisposeWindow should dispose of the objects. If you are running the debugging version of the 
  209.     //    SecretGraphics init with notices set, you will receive a notice that you had not disposed of everything.
  210.     *) 
  211.       GXDisposeShape(gRectangleShape); 
  212.     GXDisposeShape(gWindowBoundsShape);  
  213.     DisposeWindow(aWindow);
  214. END;
  215.  
  216. BEGIN
  217.     (* Generic heap initialization. *)
  218.     MaxApplZone; 
  219.     MoreMasters;
  220.     MoreMasters;
  221.     MoreMasters; 
  222.  
  223.     (*  Initialize the toolbox. *)
  224.      InitGraf(@thePort);
  225.     InitFonts;
  226.     InitWindows;
  227.     InitCursor;
  228.  
  229.     theCurs := GetCursor(watchCursor);
  230.     SetCursor(theCurs^^);
  231.  
  232.     newClient := GXNewGraphicsClient(nil, 300 * 1024, 0);
  233.  
  234.     (*
  235.     //    After we attempted to create the graphics client, we need to determine if the call
  236.     //  succeeded. If the call did not (as in the case for all GX functions), "newClient" will
  237.     //    be NULL. If it is, we alert the user to the problem. Otherwise, we will attempted to 
  238.     //    allocate the GX heap below...
  239.     *)        
  240.     IF ( newClient <> gxGraphicsClient(0)) THEN
  241.     BEGIN
  242.         (*
  243.         //    Initialize the new graphics environment and create the GX heap.
  244.         *)
  245.         GXEnterGraphics;
  246.  
  247.         (*
  248.         //    Calling GXEnterGraphics allocates the memory within the GX heap. The only reason the
  249.         //  call would not succeed is if there is not enough memory. In this case, the graphics 
  250.         //  error which will be posted is -27999 (out of memory). At this point, we have not 
  251.         //    installed an error handler, so we check for the error number corresponding to the 
  252.         //  out of memory error.
  253.         *)
  254.         IF ( GXGetGraphicsError(dummyError) <> -27999 ) THEN
  255.         BEGIN
  256.             (*
  257.             //    Create a window and attach a GX viewPort to it. By attaching the viewPort to 
  258.             //    the window will make sure that when a user moves or resizes the window all of
  259.             //    the GX drawing will occur within window. 
  260.             //
  261.             //    By the way, you cannot directly manipulate the parent viewPort attached to the
  262.             //    window, you will recieve a graphics error. This viewPort can only be manipulated
  263.             //  by the GX system. If you want to manipulate a viewPort attached to a window, it
  264.             //     _must_ be a child viewPort attached to the the parent viewPort attached to the
  265.             //    window.
  266.             *)
  267.             SetRect(windowQDRect, 50, 50, 330, 330);
  268.             gWindow := NewWindow(nil, windowQDRect, 'Rotating Rects', TRUE, noGrowDocProc,
  269.                                WindowPtr (-1), TRUE, 0);
  270.  
  271.             gTheWindowsViewPort := GXNewWindowViewPort(gWindow);
  272.             SetDefaultViewPort(gTheWindowsViewPort);
  273.  
  274.             (* Get the global bounds of the window. *)
  275.             gWindowBoundsShape := GetWindowBoundsShape;
  276.  
  277.             (* Create the GX shapes we are going to draw to the window. *)
  278.             DoInitialization(gWindow);
  279.  
  280.             SetCursor(arrow);  
  281.  
  282.             while (EventLoop = TRUE) do
  283.                 DoDraw(gWindow);   (* loop until the window is closed  *)
  284.  
  285.             DoDispose(gWindow);
  286.  
  287.             GXExitGraphics;     (* Deallocate all of the default structures *)
  288.             GXDisposeGraphicsClient(newClient);
  289.     
  290.         END
  291.         ELSE BEGIN
  292.             (*
  293.             //     Since, we can not allocate the requested size for our GX heap, we need to throw
  294.             //  away the client we created and alert the user that there is not enough memory to
  295.             //  continue.
  296.             //
  297.             //    However, you could try to create a smaller GX heap. If you decide to try to create
  298.             //     a smaller GX heap which would meet the needs of your application, you need to 
  299.             //     dispose of the client you had originally created. Why? The original client 
  300.             //    contains the GX heap size requested, which was too big, therefore you need to 
  301.             //    dispose of it and create a client requesting a smaller size and call GXEnterGraphics
  302.             //     and check for an error. 
  303.             *)
  304.             GXDisposeGraphicsClient( newClient );
  305.             DebugStr ('Unfortunately, there is not enough memory for GX, please quit an app...');
  306.         END;
  307.     END;
  308. END.
  309.  
  310.